package ffprobe

import "gitee.com/bobo-rs/goffm/utils"

type (
	// SFFProbe ffprobe服务
	SFFProbe struct {
		driver string
		src    string
		envDir string
		parse  map[string]interface{} // 视频解析内容
	}

	// StreamItem 文件流属性
	StreamItem struct {
		Index            int               `json:"index" dc:"流的索引号"`
		CodecName        string            `json:"codec_name" dc:"视频编码器的名称，这里是h264，即H.264/AVC"`
		CodecLongName    string            `json:"codec_long_name" dc:"视频编码器的完整名称，提供了更多的上下文信息"`
		Profile          string            `json:"profile" dc:"使用的H.264配置文件，这里是High"`
		CodecType        string            `json:"codec_type" dc:"流的类型，video视频流，audio音频流"`
		CodecTag         string            `json:"codec_tag" dc:"编码器的标签"`
		CodecTagString   string            `json:"codec_tag_string" dc:"编码器的标签十六进制表示"`
		PixFmt           string            `json:"pix_fmt" dc:"像素格式，这里是yuv420p，表示使用YUV 4:2:0平面格式"`
		Level            string            `json:"level" dc:"H.264的级别，定义了编码器的功能级别"`
		ColorRange       string            `json:"color_range" dc:"视频的颜色范围"`
		ColorSpace       string            `json:"color_space" dc:"颜色空间"`
		ColorTransfer    string            `json:"color_transfer" dc:"颜色转换"`
		ColorPrimaries   string            `json:"color_primaries" dc:"颜色原色"`
		ChromaLocation   string            `json:"chroma_location" dc:"色度样本的位置"`
		FieldOrder       string            `json:"field_order" dc:"字段顺序，这里是progressive，表示逐行扫描"`
		Refs             string            `json:"refs" dc:"参考帧的数量"`
		IsAvc            bool              `json:"is_avc" dc:"指示是否为AVC（高级视频编码）的布尔值"`
		NalLengthSize    string            `json:"nal_length_size" dc:"网络抽象层（NAL）单元的长度大小（以字节为单位）"`
		RFrameRate       string            `json:"r_frame_rate" dc:"帧率"`
		AvgFrameRate     string            `json:"avg_frame_rate" dc:"平均帧率"`
		TimeBase         string            `json:"time_base" dc:"时间基准，用于将时间戳转换为秒"`
		StartBts         int               `json:"start_bts" dc:"流的起始呈现时间戳"`
		StartTime        float64           `json:"start_time" dc:"起始时间"`
		DurationTs       int               `json:"duration_ts" dc:"流的持续时间（以时间戳和秒为单位）"`
		Duration         float64           `json:"duration" dc:"流的持续时间（以时间戳和秒为单位）"`
		BitRate          string            `json:"bit_rate" dc:"视频流的平均比特率"`
		BitsPerRawSample string            `json:"bits_per_raw_sample" dc:"每个原始样本的比特数"`
		NbFrames         string            `json:"nb_frames" dc:"流的帧数"`
		ExtradataSize    string            `json:"extradata_size" dc:"附加数据的大小，通常包含编码器的特定信息"`
		Disposition      StreamDisposition `json:"disposition" dc:"流的用途或属性，例如它是否是默认的、是否是原始音频或视频的翻译（配音）、是否包含评论"`
		Tags             StreamTags        `json:"tags" dc:"流的额外信息，如语言、处理程序名称和供应商I"`
	}

	// StreamTags 标签流的额外信息，如语言、处理程序名称和供应商I
	StreamTags struct {
		Language    string `json:"language" dc:"语言"`
		HandlerName string `json:"handler_name" dc:"处理程序名称，通常用于标识流的类型或用途，如“VideoHandler”或“SoundHandler”"`
		VendorId    string `json:"vendor_id" dc:"供应商ID，这里显示为[0][0][0][0]，可能表示没有特定的供应商ID或该字段未被使用"`
	}

	// StreamDisposition 字段用于描述流的用途或属性，例如它是否是默认的、是否是原始音频或视频的翻译（配音）、是否包含评论等
	StreamDisposition struct {
		Default         int `json:"default" dc:"表示该流是默认的，播放器应首选此流"`
		Dub             int `json:"dub" dc:"0 表示该流不是配音版本"`
		Original        int `json:"original" dc:"0表示该流不是原始语言版本"`
		Comment         int `json:"comment" dc:"表示流是否包含评论，0不包含"`
		Lyrics          int `json:"lyrics" dc:"表示流是否包含歌词，0不包含"`
		Karaoke         int `json:"karaoke" dc:"表示流是否包含卡拉OK文本，0不包含"`
		Forced          int `json:"forced" dc:"表示流是否包含强制字幕，0不包含"`
		HearingImpaired int `json:"hearing_impaired" dc:"表示流是否包含听力障碍字幕，0不包含"`
		VisualImpaired  int `json:"visual_impaired" dc:"表示流是否包含视觉障碍字幕，0不包含"`
		CleanEffects    int `json:"clean_effects" dc:"表示流是否包含清晰效果，0不包含"`
		AttachedPic     int `json:"attached_pic" dc:"表示流是否包含附加图片，0不包含"`
		TimedThumbnails int `json:"timed_thumbnails" dc:"表示流是否包含定时缩略图，0不包含"`
		NonDiegetic     int `json:"non_diegetic" dc:"表示流是否包含非叙事性声音，0不包含"`
		Captions        int `json:"captions" dc:"表示流是否包含字幕，0不包含"`
		Description     int `json:"description" dc:"表示流是否包含描述，0不包含"`
		Metadata        int `json:"metadata" dc:"表示流是否包含元数据，0不包含"`
		Dependent       int `json:"dependent" dc:"表示流是否包含依赖流，0不包含"`
		StillImage      int `json:"still_image" dc:"表示流是否包含静态图像，0不包含"`
		Multilayer      int `json:"multilayer" dc:"表示流是否包含多层视频，0不包含"`
	}

	// VideoStream 视频流
	VideoStream struct {
		Width       int `json:"width" dc:"视频宽度"`
		Height      int `json:"height" dc:"视频高度"`
		CodedWidth  int `json:"coded_width" dc:"编码后的视频宽度（例如，由于裁剪或填充）"`
		CodedHeight int `json:"coded_height" dc:"编码后的高度，有时与显示宽度和高度不同"`
		StreamItem
	}

	// AudioStream 音频流
	AudioStream struct {
		SampleFmt     string `json:"sample_fmt" dc:"样本格式，这里是fltp，表示浮点数样本"`
		SampleRate    string `json:"sample_rate" dc:"采样率，以Hz为单位"`
		Channels      string `json:"channels" dc:"声道数"`
		ChannelLayout string `json:"channel_layout" dc:"声道布局"`
		BitsPerSample string `json:"bits_per_sample" dc:"每个样本的比特数（对于某些编码，此值可能为零或未定义）"`
		StreamItem
	}

	// Format 封装的文件格式
	Format struct {
		Filename       string     `json:"filename" dc:"文件名"`
		NbStreams      int        `json:"nb_streams" dc:"文件中流的数量"`
		NbPrograms     int        `json:"nb_programs" dc:"文件程序"`
		NbStreamGroups int        `json:"nb_stream_groups" dc:"文件中流组"`
		FormatName     string     `json:"format_name" dc:"封装格式的名称"`
		FormatLongName string     `json:"format_long_name" dc:"封装格式完整名称"`
		StartTime      float64    `json:"start_time" dc:"文件的起始时间"`
		Duration       float64    `json:"duration" dc:"文件的总时长"`
		Size           int        `json:"size" dc:"文件的大小（以字节为单位）"`
		BitRate        int        `json:"bit_rate" dc:"文件的平均比特率"`
		ProbeScore     int        `json:"probe_score" dc:"探测分数的百分比，表示FFprobe对文件格式的信心程度"`
		Tags           FormatTags `json:"tags" dc:"相关标签信息"`
	}

	// FormatTags 文件相关的标签信息，如品牌、版本、编码器等
	FormatTags struct {
		MajorBrand       string `json:"major_brand" dc:"品牌"`
		MinorVersion     string `json:"minor_version" dc:"版本"`
		CompatibleBrands string `json:"compatible_brands" dc:"兼容品牌"`
		Encoder          string `json:"encoder" dc:"编码器"`
	}
)

const (
	defaultDriver = `ffprobe`
)

// New 实例
func New(envDir ...string) *SFFProbe {
	envFFMpeg := utils.GetFFMpegEnv(envDir...)
	return &SFFProbe{
		driver: envFFMpeg + defaultDriver,
		envDir: envFFMpeg,
	}
}

// Src 设置文件地址
func (p *SFFProbe) Src(src string) *SFFProbe {
	p.src = src
	return p
}
